import { Object3D } from "three/src/core/Object3D";
import Polyline from "../../models/Polyline"
import { App } from "../../../application";
import { Point } from "../../../renderExtension/types/Point";
import Const from "../../../application/constants/Const";
import MeshUtil from "../../../renderExtension/utils/MeshUtil";

export default class RouteLine {
    private app: App;
    private realRoute: Polyline;
    private hideRoute: Polyline;
    // private lineClickCallback;
    private globalCallback;
    private isIntersect = false;

    private flightParam: {
        realLine: Polyline,
        lineScale?: number,
        sphereScale?: number,
        grounds?: Array<Object3D>,
        minDistanceFromGround: number,
        maxDistanceFromGround: number,
        sidewipeDistance: number,
    }

    public constructor(flightParam: {
        realLine: Polyline,
        lineScale?: number,
        sphereScale?: number,
        grounds?: Array<Object3D>,
        minDistanceFromGround: number,
        maxDistanceFromGround: number,
        sidewipeDistance: number,
    }, globalCallback) {
        this.app = App.getInstance();
        this.flightParam = flightParam;
        this.globalCallback = globalCallback;
        this.initRouteLine();
    }

    private initRouteLine() {
        this.realRoute = this.flightParam.realLine
        this.realRoute['canNotSelect'] = false; //true //不参与射线拾取
        this.realRoute['flightRouteTag'] = true;
        this.realRoute['flightClick'] = this.globalCallback;
        this.realRoute.renderOrder = Const.RenderOrder.RouteLine;
        this.app.add(this.realRoute)

        let hideLineParam = {}
        Object.assign(hideLineParam, this.flightParam)
        hideLineParam['lineWidth'] =
            this.realRoute.param.lineWidth * this.flightParam.lineScale
        hideLineParam['color'] = '#9370DB'
        let newPointArray = []
        this.realRoute.getPointArray().forEach((element) => {
            newPointArray.push(element)
        })
        hideLineParam['pointArray'] = newPointArray
        this.hideRoute = new Polyline(hideLineParam)
        this.hideRoute.material.visible = false
        this.hideRoute['flightRouteTag'] = true
        this.hideRoute['canNotSelect'] = false; //true //先不参与射线拾取，等对realRoute的末尾添加点的操作完成后，再开启射线拾取
        this.hideRoute['flightClick'] = this.globalCallback;
        this.app.add(this.hideRoute)
    }

    public lineClickEvent(e) {
        let lnglat = e.lnglat
        let insertedPointMsg = this.realRoute.insertPoint(lnglat)
        if (!insertedPointMsg) {
            return
        }

       this.intersectObjects();

        let pointArray = this.realRoute.getPointArray()
        this.hideRoute.replacePointArray(pointArray)

        return insertedPointMsg;
    }

    public addPoint(point) {
        this.realRoute.addPoint(point)
        this.hideRoute.addPoint(point)

        this.intersectObjects();
    }

    public removePoint(index: number) {
        this.realRoute.removePoint(index)
        this.hideRoute.removePoint(index)

        this.intersectObjects();
    }

    public updatePoint(index: number, newPoint: Point, isIntersect:boolean = true) {
        this.realRoute.updatePoint(index, newPoint.clone());
        this.hideRoute.updatePoint(index, newPoint.clone());

        if(isIntersect){
            this.intersectObjects();
        }
    }

    public dispose(){
        MeshUtil.dispose(this.realRoute);
        MeshUtil.dispose(this.hideRoute);
        
        // this.hideRoute['canNotSelect'] = true //关闭射线拾取

        this.hideRoute['flightClick'] = null
    }

    public getPointArray(){
        return this.realRoute.getPointArray();
    }

    public intersectObjects(){
        let sidewipeDistance: number = this.flightParam.sidewipeDistance || 5;
        sidewipeDistance = sidewipeDistance * 2; //这里乘以2是因为用到了box相交检测，box的长宽向两个方向扩展

        //intersectState是0表示没有相交/擦边，1表示有相交点，2表示有擦边点
        let intersectState = this.realRoute.intersectObjects(this.flightParam.grounds, sidewipeDistance).intersectState;
        this.isIntersect = (intersectState == 0 ? false : true);
        if(intersectState == 1){ //有相交点
            this.app.fireEvent(Const.FlightRoute.throughWall);
        }else if(intersectState == 2){ //有擦边点
            this.app.fireEvent(Const.FlightRoute.sideWipe);
        }
    }

    public checkSafe(): boolean{
        return !this.isIntersect;
    }
}